package pr.lanmu.config.filter;

import cn.hutool.core.io.IoUtil;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import pr.lanmu.AppApplication;
import pr.lanmu.config.util.Current;
import pr.lanmu.config.util.Log;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ConcurrentHashMap;

import static pr.lanmu.AppApplication.linkTracingTimes;

/**
 * 过滤器
 */
@Component
@WebFilter(filterName = "filter", urlPatterns = "/*")
public class RequestInfoFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        //todo 过滤危险数据

        //跨域
        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, PATCH");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");
        //清除threadLocal数据，防止线程池中线程复用导致的问题
        Current.clear();
        //填充threadLocal数据
        Current.setRequest((HttpServletRequest) request);
        //清除链路追踪次数
        linkTracingTimes.remove();
        //todo 递归记录有误，待优化
        linkTracingTimes.set(new ConcurrentHashMap<>());
        //引入线程内使用的脚本引擎，反复使用
        doSetScriptEngine();
        chain.doFilter(request, response);
    }

    private void doSetScriptEngine() {
        try {
            ScriptEngine scriptEngine = AppApplication.scriptEngine.get();
            if (scriptEngine != null) return;
            //使用js引擎
            ScriptEngine context = new ScriptEngineManager().getEngineByName("graal.js");
            ResourceLoader resourceLoader = new DefaultResourceLoader();
            InputStream inputStream = resourceLoader.getResource("js/moment.js").getInputStream();
            // 引入 moment.js 库
            try {
                context.eval(new String(IoUtil.readBytes(inputStream), StandardCharsets.UTF_8));
            } catch (ScriptException e) {
                Log.error("引入moment.js库失败：{}", e);
            }
            AppApplication.scriptEngine.set(context);
        } catch (IOException e) {
            Log.error("读取moment.js文件失败：{}", e);
        } finally {
            Log.warn(AppApplication.scriptEngine.get().toString());
        }
    }

    @Override
    public void destroy() {
    }
}
